由于 Let's Encrypt
等免费证书的存在,各位站长都可以很容易的加固自己的网站。然而 HTTPS 不是万能药,并不是加入 HTTPS 支持就万事大吉了。
譬如说,就算你加入了 HTTPS 支持,要如何让用户使用 HTTPS 连接呢?包括笔者在内,估计没有人会手工输入那个奇怪的 https://
协议头,而浏览器总是会把无协议头的网址默认当做 http
协议。于是,当用户输入了你网址的域名回车的时候,用户的电脑就和你的服务器建立了非安全的连接。有人说他们已经配置服务器当用户使用 HTTP
协议连接时重定向至 HTTPS
,但这样并不完全解决问题:就算返回的是一个 301 重定向,未加密就是未加密,中间人可以为所欲为,比如读取用户上传的请求头,篡改服务器返回的 301 地址到别的网站等。
必须由一种机制强制用户使用 HTTPS
协议连接服务器,这就是 HSTS 的作用。
什么是 HSTS
HTTP严格传输安全(英语:HTTP Strict Transport Security,缩写:HSTS)是一套由互联网工程任务组发布的互联网安全策略机制。网站可以选择使用 HSTS 策略,来让浏览器强制使用 HTTPS 与网站进行通信,以减少会话劫持风险。
对于启用 HSTS 的网站,浏览器会做到以下几点:
-
强制使用 HTTPS 协议连接。对于不安全的访问协议,浏览器会在内部将其重定向至 HTTPS 协议。包括并不限于
- 用户没有输入协议头
- 用户输入了
http://
协议头
- 当浏览器发现服务器证书错误,强制阻止用户建立连接
如何启用 HSTS
添加返回头:
Strict-Transport-Security: max-age=<过期时间>; includeSubDomains
其中 includeSubDomains
是可选的,表示给当前域名下的子域名也启用 HSTS 支持。
值得注意的是:客户端必须与服务器建立安全连接时(当使用 HTTPS 协议连接并且无证书错误) Strict-Transport-Security
头才会被浏览器认可。这是因为非安全连接下中间人可以添加或者删除这个头,在建立真正安全的连接时一切都是不可信的。
如果要提前关闭 HSTS,可以使用类似清除 Cookie 的做法:
Strict-Transport-Security: max-age=0; includeSubDomains
同样需要建立安全连接才会生效。
预加载 HSTS
前面提到,HSTS 是服务器返回给浏览器的一个返回头,并且只会在建立安全连接时才会生效。那么就引出了另一个问题:如果用户从未访问过你的网站,而在第一次访问就被劫持了怎么办?
所以问题在于,除非客户端与服务器建立过连接,否则浏览器不知道服务器是否支持 HTTPS 请求,更不知道该站点是否想要启用 HSTS。谷歌想出了一个办法:把想启用 HSTS 的所有站点的域名预先写进浏览器代码不就好了。这就是 Preloading Strict Transport Security
。
谷歌维护了一个名为 HSTS Preload List Submission
的网站,专门用于申请让浏览器给各站点内置开启 HSTS
支持。申请预加载 HSTS 需要站点满足更为严格的条件:
- 提供一个有效的证书。
- 如果你的站点同时启用了 HTTP 支持(监听 80 端口),必须把 HTTP 重定向到同一域名的 HTTPS 网址(例如将
http://domain.com
重定向到https://www.domain.com
是不可以的) - 所有子域名也必须启用 HTTPS 连接
-
返回一个满足以下条件的 HSTS 头
-
max-age
至少需要 18 个月(大于等于 10886400 秒) - 必须指定
includeSubDomains
- 必须指定
preload
(preload 是谷歌给 HSTS 头添加的扩展值) - 如果这个域名会重定向到另一个域名,前面的域名也必须添加
HSTS
头(例如 https://domain.com 重定向到 https://www.domain.com,前者需要添加HSTS
头)
-
满足这些条件后,你就可以在其官方网站上给你的域名申请预加载 HSTS。如果申请通过,等待一段时间后你的域名就会被 Hard code 到浏览器内部了。不仅是 Chrome,IE、Edge、Firefox 都会采用。可以用这个网站检测你域名是否支持预加载 HSTS。
PS:EOI 的顶级域名 eoitek.com 同样支持预加载 HSTS,不来转转么?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。